import csv
import time
import os
import traceback
import sys
import json

# 确保能够正确导入WalmartAPI
current_dir = os.path.dirname(os.path.abspath(__file__))
if current_dir not in sys.path:
    sys.path.append(current_dir)

from walmart_api import WalmartAPI

def create_product_data_for_catalog_match(sku, product_id, product_id_type, price, shipping_weight=None, condition=None):
    """创建用于Walmart目录匹配的产品数据格式"""
    
    # 构建目录匹配格式的产品数据
    product_data = {
        "sku": sku,
        "productIdentifiers": [
            {
                "productIdType": product_id_type,
                "productId": product_id
            }
        ],
        "price": price
    }
    
    # 添加可选字段
    if shipping_weight is not None:
        product_data["ShippingWeight"] = shipping_weight
        
    if condition is not None:
        product_data["condition"] = condition
    
    return product_data

def validate_credentials(client_id, client_secret):
    """验证API凭证格式"""
    if not client_id or not client_secret:
        return False, "Client ID和Client Secret不能为空"
    
    client_id = client_id.strip()
    client_secret = client_secret.strip()
    
    # 基本格式验证
    if len(client_id) < 10:
        return False, "Client ID格式无效(长度太短)"
    if len(client_secret) < 20:
        return False, "Client Secret格式无效(长度太短)"
    
    return True, "凭证格式有效"

def validate_product_data(product, row_num=None):
    """验证产品数据格式"""
    issues = []
    
    # 检查必填字段
    if 'sku' not in product or not product['sku']:
        issues.append("缺少sku字段")
    
    if 'productIdentifiers' not in product or not product['productIdentifiers']:
        issues.append("缺少productIdentifiers字段")
    else:
        identifiers = product['productIdentifiers']
        if not isinstance(identifiers, list) or not identifiers:
            issues.append("productIdentifiers必须是非空列表")
        else:
            identifier = identifiers[0]
            if 'productIdType' not in identifier or not identifier['productIdType']:
                issues.append("缺少productIdType字段")
            if 'productId' not in identifier or not identifier['productId']:
                issues.append("缺少productId字段")
    
    if 'price' not in product:
        issues.append("缺少price字段")
    
    # 检查格式
    if 'price' in product:
        try:
            price = float(product['price'])
            if price <= 0:
                issues.append("价格必须大于0")
        except (ValueError, TypeError):
            issues.append("价格格式无效")
    
    if 'ShippingWeight' in product:
        try:
            weight = float(product['ShippingWeight'])
            if weight <= 0:
                issues.append("重量必须大于0")
        except (ValueError, TypeError):
            issues.append("重量格式无效")
    
    # 组装错误消息
    if issues:
        row_info = f"第{row_num}行" if row_num else "产品"
        return False, f"{row_info}数据验证失败: {', '.join(issues)}"
    
    return True, "产品数据格式有效"

def upload_products_from_csv(client_id, client_secret, csv_file_path):
    """从CSV文件批量上传产品到沃尔玛平台（使用目录匹配API）"""
    products = []
    valid_product_count = 0
    
    print(f"开始处理批量上传，Client ID: {client_id[:8] if len(client_id) >= 8 else '***'}...")
    
    # 验证凭证格式
    is_valid, message = validate_credentials(client_id, client_secret)
    if not is_valid:
        print(f"错误: {message}")
        return None
    
    # 创建API客户端
    try:
        walmart_api = WalmartAPI(client_id, client_secret)
        print("已创建WalmartAPI实例")
    except Exception as e:
        print(f"创建API客户端实例失败: {e}")
        traceback.print_exc()
        return None
    
    # 验证认证
    try:
        token = walmart_api.get_token()
        if not token:
            print("获取令牌失败: 返回的令牌为空")
            return None
            
        print(f"认证成功! 获取令牌: {token[:10]}...")
    except Exception as e:
        print(f"认证失败: {e}")
        traceback.print_exc()
        return None
    
    # 检查CSV文件是否存在
    if not os.path.isabs(csv_file_path):
        # 如果不是绝对路径，那么相对于当前目录
        csv_file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), csv_file_path)
    
    print(f"CSV文件路径: {csv_file_path}")
    
    if not os.path.exists(csv_file_path):
        print(f"错误: CSV文件不存在 - {csv_file_path}")
        return None
    
    # 读取CSV文件
    try:
        with open(csv_file_path, 'r', encoding='utf-8') as csvfile:
            reader = csv.DictReader(csvfile)
            
            if not reader.fieldnames:
                print("错误: CSV文件格式无效或为空")
                return None
                
            print(f"CSV列头: {reader.fieldnames}")
            
            # 验证CSV文件格式
            required_fields = ['sku', 'product_id', 'product_id_type', 'price']
            missing_fields = [field for field in required_fields if field not in reader.fieldnames]
            if missing_fields:
                print(f"错误: CSV文件缺少必要的列: {', '.join(missing_fields)}")
                return None
            
            for row_num, row in enumerate(reader, 1):
                try:
                    # 检查必填字段
                    missing_fields = [field for field in required_fields if field not in row or not row[field]]
                    
                    if missing_fields:
                        print(f"警告: 第{row_num}行缺少必填字段: {', '.join(missing_fields)}")
                        continue
                    
                    # 创建目录匹配格式的产品数据
                    product = create_product_data_for_catalog_match(
                        sku=row['sku'],
                        product_id=row['product_id'],
                        product_id_type=row['product_id_type'],
                        price=float(row['price']),
                        shipping_weight=float(row['shipping_weight']) if 'shipping_weight' in row and row['shipping_weight'] else None,
                        condition=row.get('condition')
                    )
                    
                    # 验证产品数据
                    is_valid, message = validate_product_data(product, row_num)
                    if not is_valid:
                        print(f"警告: {message}")
                        continue
                    
                    products.append(product)
                    valid_product_count += 1
                    print(f"已处理第{row_num}行: SKU={row['sku']}, 产品ID={row['product_id']}")
                    
                except Exception as e:
                    print(f"处理第{row_num}行时出错: {e}")
                    traceback.print_exc()
    except Exception as e:
        print(f"读取CSV文件失败: {e}")
        traceback.print_exc()
        return None
    
    print(f"CSV处理完成: 共读取{row_num}行数据，有效产品{valid_product_count}个")
    
    # 批量上传
    if products:
        try:
            print(f"开始上传 {len(products)} 个产品到Walmart目录...")
            
            # 测试API连接
            print("先测试API连接...")
            success, message = walmart_api.test_api_connection()
            if not success:
                print(f"API连接测试失败: {message}")
                print("建议: 请检查您的API凭证和网络连接")
                return None
            else:
                print(f"API连接测试成功: {message}")
            
            # 对产品数据进行分组，每组最多10个产品
            batch_size = 5  # 减小批次大小以降低失败风险
            batches = [products[i:i + batch_size] for i in range(0, len(products), batch_size)]
            
            print(f"将 {len(products)} 个产品分成 {len(batches)} 批处理，每批最多 {batch_size} 个产品")
            
            results = []
            for batch_num, batch in enumerate(batches, 1):
                print(f"正在处理第 {batch_num}/{len(batches)} 批产品 ({len(batch)} 个)...")
                
                # 打印批次摘要
                batch_summary = []
                for idx, item in enumerate(batch, 1):
                    sku = item.get('sku', 'unknown')
                    product_id = item.get('productIdentifiers', [{}])[0].get('productId', 'unknown')
                    batch_summary.append(f"{idx}. SKU: {sku}, ID: {product_id}")
                
                print("批次产品摘要:")
                for summary in batch_summary:
                    print(f"  {summary}")
                
                # 上传批次
                try:
                    result = walmart_api.bulk_upload_products(batch)
                    feed_id = result.get('feedId')
                    print(f"批次 {batch_num} 上传完成，任务ID: {feed_id}")
                    results.append(result)
                    
                    # 批次之间暂停几秒，避免API限制
                    if batch_num < len(batches):
                        pause_time = 5  # 延长暂停时间
                        print(f"暂停{pause_time}秒后上传下一批...")
                        time.sleep(pause_time)
                except Exception as batch_error:
                    print(f"批次 {batch_num} 上传失败: {batch_error}")
                    traceback.print_exc()
                    # 继续处理下一批
                    continue
            
            # 返回上传结果摘要
            if results:
                print(f"\n上传摘要: 共有 {len(batches)} 批次，成功上传 {len(results)} 批次")
                
                # 如果至少有一个批次成功，检查最后一个成功批次的状态
                last_result = results[-1]
                feed_id = last_result.get('feedId')
                
                if feed_id:
                    # 检查上传状态
                    print(f"等待5秒后检查上传状态 (Feed ID: {feed_id})...")
                    time.sleep(5)
                    try:
                        status = walmart_api.check_feed_status(feed_id)
                        feed_status = status.get('feedStatus', '未知')
                        print(f"当前上传状态: {feed_status}")
                        
                        # 如果有详细信息，打印出来
                        if 'ingestionErrors' in status and status['ingestionErrors']:
                            print("\n上传错误信息:")
                            for error in status['ingestionErrors']:
                                print(f"  - {error.get('description', '未知错误')}")
                        
                        if feed_status.lower() == 'processed':
                            print("上传任务已处理完成！")
                    except Exception as status_error:
                        print(f"检查上传状态失败: {status_error}")
                
                return {
                    'success': True,
                    'total_batches': len(batches),
                    'successful_batches': len(results),
                    'last_feed_id': feed_id if 'feed_id' in locals() else None,
                    'results': results
                }
            else:
                print("没有批次成功上传")
                return {
                    'success': False,
                    'message': "所有批次上传失败"
                }
        except Exception as e:
            print(f"批量上传产品失败: {e}")
            traceback.print_exc()
            return {
                'success': False,
                'message': str(e)
            }
    else:
        print("没有找到有效的产品数据")
        return {
            'success': False,
            'message': "没有找到有效的产品数据"
        }

if __name__ == "__main__":
    # 示例用法
    client_id = "0b05fa33-3e2b-4b9f-9d2d-b3cf647f56f7"
    client_secret = "c-XIcBx4l0mu0Pjs9Sd-7nb1n6tSzfxW2dAnsbfWcaKoXZ7jQu3h-APfYuj744C7d8u8t-O4jYxH3Wj8UqeCPQ"

    csv_file = "products_catalog_match.csv"
    
    result = upload_products_from_csv(client_id, client_secret, csv_file)
    
    # 打印结果摘要
    if result:
        if result.get('success'):
            print(f"\n上传成功！共 {result['total_batches']} 批次，成功 {result['successful_batches']} 批次")
            if result.get('last_feed_id'):
                print(f"最后一个Feed ID: {result['last_feed_id']}")
        else:
            print(f"\n上传失败：{result.get('message', '未知错误')}")
    else:
        print("\n上传失败：没有返回结果") 